/**
 * @author Francesco Rosso, matr 592057
 */
package pcd1112.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JOptionPane;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import pcd1112.model.Ambiente;
import pcd1112.model.Config;
import pcd1112.model.Hypervisor;
import pcd1112.model.eccezioni.ErrorException;
import pcd1112.view.ClientGUI;

public class Controller implements ActionListener {

	private class Simulations extends Thread {

		private ClientGUI GUI;
		private boolean fermatutto = false;

		public Simulations(ClientGUI GUI) {
			this.GUI = GUI;
		}

		private void singleSimulation() throws ErrorException {
			Hypervisor h = new Hypervisor();
			h.setServerUrl(GUI.getRmiHost().getText());
			h.init();
			GUI.getNodi().aggiorna();
			h.startSimulation();
			if (!fermatutto) {
				String result = h.sendResults();
				GUI.appendResult(result + "\n");
			}
		}

		public void run() {
			try {
				GUI.getStartButton().setText("Pause");
				GUI.getStopButton().setEnabled(true);
				GUI.getConfigurationType().setEnabled(false);
				GUI.clearResult();
				Config.getConfig().inizializza();
				setPauseRequest(false);
				fermatutto = false;
				for (int i = 0; i < Config.getConfig().getNSIM() && !fermatutto; i++) {
					GUI.setProgress(i + 1, Config.getConfig().getNSIM());
					singleSimulation();
				}
				GUI.getStopButton().setEnabled(false);
				GUI.getConfigurationType().setEnabled(true);
				GUI.getStartButton().setText("Start");
			} catch (ErrorException exc) {
				JOptionPane.showMessageDialog(GUI.getFrame(), exc.getMessage()
						+ "\n" + exc.getDetails(), "Simulation error!",
						JOptionPane.ERROR_MESSAGE);
			} finally {
				GUI.getStopButton().setEnabled(false);
				GUI.getConfigurationType().setEnabled(true);
				GUI.getStartButton().setText("Start");
			}
			if (fermatutto) {
				JOptionPane.showMessageDialog(GUI.getFrame(),
						"Simulation stopped", "Simulation message",
						JOptionPane.INFORMATION_MESSAGE);
			}

		}

		public void stopRequest() {
			fermatutto = true;
			Ambiente.getAmbiente().setStopEverything(true);
		}

		public synchronized void setPauseRequest(boolean value) {
			if (value) {
				GUI.getStartButton().setText("Resume");
				Ambiente.getAmbiente().pause();
			} else {
				GUI.getStartButton().setText("Pause");
				Ambiente.getAmbiente().resume();
			}
		}
	}

	private class SliderListener implements ChangeListener {

		@Override
		public void stateChanged(ChangeEvent e) {
			JSlider source = (JSlider) e.getSource();
			if (!source.getValueIsAdjusting()) {
				int delay = (int) source.getValue();
				Config.getConfig().setDelay(delay);
			}
		}
	}

	ClientGUI GUI;
	Simulations sim;

	public Controller(ClientGUI g) {
		this.GUI = g;
		GUI.getStartButton().addActionListener(this);
		GUI.getStopButton().addActionListener(this);
		GUI.getMsecSlider().addChangeListener(new SliderListener());
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		String pressed = e.getActionCommand();
		if (pressed == "Start") {
			if (GUI.getConfigurationType().getSelectedItem().equals("Real"))
				Config.getConfig().setCurrentMode(Config.Mode.real);
			else
				Config.getConfig().setCurrentMode(Config.Mode.teacherDefault);
			Config.getConfig().setUrl(GUI.getConfUrl().getText());
			sim = new Simulations(GUI);
			sim.start();
		}
		if (pressed == "Stop") {
			sim.stopRequest();
		}
		if (pressed == "Pause") {
			sim.setPauseRequest(true);
		}
		if (pressed == "Resume") {
			sim.setPauseRequest(false);
		}
	}

}
